using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace GameEditor.Common.Controls
{

    public class HueBlacknessPicker : Control
    {
        private const int HPadding = 10;
        private const int VPadding = 10;




        public HueBlacknessPicker()
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }
        public event EventHandler ColorChanged;
        private float blackness;

        public float Blackness
        {
            get { return blackness; }
            set { blackness = MathHelper.Saturate(value); }
        }
        private float hue;

        public float Hue
        {
            get { return hue; }
            set { hue = MathHelper.Clamp(0.0f, 360.0f, value); }
        }

        public Color CurrentColor
        {
            get
            {
                Bitmap huemap = Resource.HueBitmap;
                int y = (int)MathHelper.IntervalMap(blackness,
                    new Range<float>(0, 1),
                    new Range<float>(0, huemap.Height - 1));

                int x = (int)MathHelper.IntervalMap(hue,
                    new Range<float>(0, 360),
                    new Range<float>(0, huemap.Width - 1));
                Color c = huemap.GetPixel(x, y);
                return c;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;
            Rectangle imageRect = new Rectangle(HPadding, VPadding, Width - 2 * HPadding, Height - 2 * VPadding);
            g.DrawImage(Resource.HueBitmap, imageRect);

            //draw arrow
            int arrowLeft = (int)MathHelper.IntervalMap(
                hue,
                new Range<float>(0, 360),
                new Range<float>(HPadding, Width - HPadding)
                );
            int arrowTop = (int)MathHelper.IntervalMap(
                blackness,
                new Range<float>(0, 1),
                new Range<float>(VPadding, Height - VPadding)
                );
            Point pt1 = new Point(arrowLeft, VPadding);
            Point pt2 = new Point(pt1.X - 5, pt1.Y - 10);
            Point pt3 = new Point(pt1.X + 5, pt1.Y - 10);

            Point pt4 = new Point(HPadding, arrowTop);
            Point pt5 = new Point(pt4.X - 10, pt4.Y - 5);
            Point pt6 = new Point(pt4.X - 10, pt4.Y + 5);

            using (GraphicsPath path = new GraphicsPath())
            {
                path.StartFigure();
                path.AddLine(pt1, pt2);
                path.AddLine(pt2, pt3);
                path.AddLine(pt3, pt1);
                path.CloseFigure();
                path.StartFigure();
                path.AddLine(pt4, pt5);
                path.AddLine(pt5, pt6);
                path.AddLine(pt6, pt4);
                path.CloseFigure();
                g.FillPath(Brushes.White, path);
            }
            g.DrawLine(Pens.Black, pt1, pt2);
            g.DrawLine(Pens.Black, pt1, pt3);
            g.DrawLine(Pens.Black, pt2, pt3);

            g.DrawLine(Pens.Black, pt4, pt5);
            g.DrawLine(Pens.Black, pt5, pt6);
            g.DrawLine(Pens.Black, pt6, pt4);

            //draw cross arrow
            int y = arrowTop;
            int x = arrowLeft;
            int halfLength = 5;
            g.DrawLine(Pens.Black, x - halfLength, y - 1, x + halfLength, y - 1);
            g.DrawLine(Pens.White, x - halfLength, y + 0, x + halfLength, y + 0);

            g.DrawLine(Pens.Black, x - 1, y - halfLength, x - 1, y + halfLength);
            g.DrawLine(Pens.White, x + 0, y - halfLength, x + 0, y + halfLength);

        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (e.Button == MouseButtons.Left)
                UpdateParameters(e.Location);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (e.Button == MouseButtons.Left)
                UpdateParameters(e.Location);
        }
        private void UpdateParameters(Point pt)
        {
            blackness = MathHelper.IntervalMap
                (1.0f * pt.Y,
                new GameEditor.Common.Range<float>(VPadding, Height - VPadding),
                new GameEditor.Common.Range<float>(0, 1));
            blackness = MathHelper.Saturate(blackness);


            hue = MathHelper.IntervalMap
                (1.0f * pt.X,
                new GameEditor.Common.Range<float>(HPadding, Width - HPadding),
                new GameEditor.Common.Range<float>(0, 360));
            hue = MathHelper.Clamp(0.0f, 360.0f, hue);

            Invalidate();
            if (ColorChanged != null)
                ColorChanged(this, EventArgs.Empty);
        }

    }

}
